package com.rfsp.common.base;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.rfsp.common.util.JsonUtil;
import org.apache.commons.lang.StringUtils;

import com.rfsp.common.enums.SystemConst;
public class BasePOJO implements Serializable{
	
	/**
	 * 序列化
	 */
	private static final long serialVersionUID = 1L;
	
	private static final String BASE_CLASS_NAME = "java.lang.Object";
	private static final String PREFIX_GET = "get";
	private static final String PREFIX_SET = "set";

	public Long getId() {
		return 0L;
	}

	public void setId(Long id) {
		
	}
	
	
	public Map<String,Object> toHashMap() {
		Map<String,Object> dataMap = new HashMap<String,Object>();
		Class clazz = this.getClass();
		while(clazz!=null && !clazz.getName().equals(BASE_CLASS_NAME)){
			this.toHashMap(clazz, dataMap);
			clazz = clazz.getSuperclass();
		}
		return dataMap;
	}
	
	private void toHashMap(Class clazz,Map<String,Object> dataMap){
		try{
			Field[] fields = clazz.getDeclaredFields();
			if(fields!=null && fields.length>0){
				for(int i = 0;i<fields.length;i++){
					Method method = this.retriveMethod(clazz,fields[i], this.orgGetMethodName(fields[i]));
					if(method!=null){
						Object value = method.invoke(this, new Object[]{});
						if(value==null){
							dataMap.put(fields[i].getName(), SystemConst.EMPTY);
							continue;
						}
						if(value instanceof Collection){
							Collection valColl = (Collection)value;
							if(valColl.size()>0){
								List<Map<String,Object>> dataList = new ArrayList<Map<String,Object>>();
								for(Iterator iter = valColl.iterator();iter.hasNext();){
									Object iterObj = iter.next();
									if(iterObj instanceof BasePOJO){
										dataList.add(((BasePOJO)iterObj).toHashMap());
									}
								}
								dataMap.put(fields[i].getName(), dataList);
							}
						}else{
							dataMap.put(fields[i].getName(),value);
						}
					}
				}
			}
		}catch(Throwable e){
			e.printStackTrace();
		}
	}
	
	private String orgGetMethodName(Field field){
		String fieldName = field.getName();
		String methodName = null;
		if(fieldName.length()>1){
			methodName = PREFIX_GET+StringUtils.substring(fieldName, 0, 1).toUpperCase()+StringUtils.substring(fieldName, 1);
		}else{
			methodName=PREFIX_GET+fieldName.toUpperCase();
		}
		
		return methodName;
	}
	
	
	private Method retriveMethod(Class clazz,Field field,String methodName){
		Method[] methods = clazz.getDeclaredMethods();
		for(int i = 0;i<methods.length;i++){
			if(methods[i].getName().equals(methodName)){
				return methods[i];
			}
		}
		return null;
	}

	public String toString(){
		try {
			return JsonUtil.toJson(this);
		} catch (JsonProcessingException e) {
			return this.getClass().getSimpleName();
		}
	}
	
}
